--[[
	Whisperloot Frame reimplementded as library to allow splitting off to separate file
]]

local wfLib, oldMinor = LibStub:NewLibrary("WhisperLootFrames", 3)
local AceGUI = LibStub("AceGUI-3.0")
--local tablet = AceLibrary("Tablet-2.0")

if not wfLib then
  return	-- already loaded and no upgrade necessary
end

wfLib.embeds = wfLib.embeds or {} -- table containing objects this lib is embedded in.
wfLib.commands = wfLib.commands or {} -- table containing commands registered
wfLib.weakcommands = wfLib.weakcommands or {} -- table containing self, command => func references for weak

--[[
Bid frame for WhisperLoot3 (so we can dump the rather ghastly XML)


Layout:
  --------------------------------------      -----------------
|-| title                               |-| |-| title         |-|
| --------------------------------------- | | ----------------- |
| |"Item"|                                | | Bidder - Bid    |^|
| |<item link/name>---------------------| | |                 | |
| |"Time left"|          |"Current bid  | | |                 | |
| |<time left>---|       |<curr. bid>---| | |                 | |
| |"Winner"|                              | |                 | |
| |<High Bidders List>------------------| | |                 |X|
|                                         | |                 | |
|  --------------                         | |                 | |
|  |   Start     |                        | |                 | |
|  --------------                         | |                 | |
|  --------------    ----------------     | |                 | |
|  |   Stop      |   |    Cancel    |     | |                 | |
|  --------------    ----------------     | |                 |v|
------------------------------------------| |-------------------|
]]

local today = date("%d-%b-%y")

local debug = false
local debuglvl = 9

function wfLib:SetDebug (value, lvl)
	debug = value
	debuglvl = lvl
	
	if debug then
		wfLib:dbgPrint(0,"-- wfLib debug on, msg lvl " .. debuglvl)
	end
end

function wfLib:dbgPrint(lvl, msg)
	if debug and debuglvl >= lvl then		print("|cffffff00Debug - " .. msg)	endend

-- get a reference to our 'parent' addon
local addon = nil
function wfLib:SetAddon(parent)
	addon = parent
	if (parent) then
		wfLib:dbgPrint (9, "Addon set to " .. addon:GetName())
	else
		wfLib:dbgPrint (9, "Addon set to nil")
	end
end

--========================================================================================--
-- The Auction frame
--========================================================================================--
local auctionFrame
function wfLib:GetWLAuctionFrame()
	if auctionFrame ~= nil then return auctionFrame end

	local fName = "wlAuctionFrame"
	local fWidth = 400
	local fHeight = 290
	
	local function getTexture(parentFrame)
		local tex = parentFrame:CreateTexture(nil, "ARTWORK")
		tex:ClearAllPoints()
		tex:SetWidth(parentFrame:GetWidth())
		tex:SetHeight(parentFrame:GetHeight())
		tex:SetPoint("CENTER", parentFrame, "CENTER", 0, 0)
		return tex
	end

	local frame = CreateFrame("Frame", fName, UIParent)
	frame:Hide()
	frame:SetWidth(fWidth)
	frame:SetHeight(fHeight)
	frame:SetResizable(true)

	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
		edgeFile="Interface\\AddOns\\whisperloot3\\textures\\otravi-semi-full-border", edgeSize = 32,
		insets = {left = 1, right = 1, top = 20, bottom = 1},
	})
	
	frame:SetBackdropColor(24/255, 24/255, 24/255)
	frame:ClearAllPoints()
	
	frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
	frame:EnableMouse(true)
	frame:RegisterForDrag("LeftButton")
	frame:SetMovable(true)

	frame:SetScript("OnDragStart", function(self)
		self:StartMoving()
	end)
	frame:SetScript("OnDragStop", function(self)
		self:StopMovingOrSizing()
	end)

-- Frame header
	local header = frame:CreateFontString(nil,"OVERLAY")
	header:ClearAllPoints()
	header:SetWidth(240)
	header:SetHeight(15)
	header:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -14)
	header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -14)
	header:SetFont("Fonts\\FRIZQT__.TTF", 12)
	header:SetJustifyH("LEFT")
	header:SetText("Whisperloot Auction")
	header:SetShadowOffset(.8, -.8)
	header:SetShadowColor(0, 0, 0, 1)

-- Form labels and fields
	-- Item
	local afItemLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	afItemLabel:SetTextColor(0.1, 1, 1, 1)
	afItemLabel:SetText("Item")
	afItemLabel:ClearAllPoints()
	afItemLabel:SetPoint("TOPLEFT", frame, "TOPLEFT", 10, -40)
	
	afItemName = CreateFrame("EditBox", "wlItemName", frame)
	afItemName:ClearAllPoints()
	afItemName:SetPoint("TOPLEFT", afItemLabel, "BOTTOMLEFT", 0, -5)
	afItemName:SetFontObject(ChatFontNormal)
	afItemName:SetWidth(frame:GetWidth()-20)
	afItemName:SetHeight(20)
	afItemName:SetBackdropColor(0.4, 0,4, 0,4, 0.7)
	afItemName:SetText("")
	afItemName:SetAutoFocus(false)
	afItemName:SetMultiLine(false)
	afItemName:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	local afItemTex = getTexture(afItemName)
	afItemTex:SetTexture(0.3, 0.3, 0.3, 0.7)

	-- Timer slider label
	local tLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	tLabel:SetTextColor(0.1, 1, 1, 1)
	tLabel:SetText("Timer")
	tLabel:ClearAllPoints()
	tLabel:SetPoint("TOPLEFT", afItemName, "BOTTOMLEFT", 0, -10)
	
	-- Timer slider
	local tSlider = CreateFrame("Slider", "wlTimerSlider", frame, "OptionsSliderTemplate")
	tSlider:ClearAllPoints()
	tSlider:SetPoint("TOPLEFT", tLabel, "BOTTOMLEFT", 0, -5)
	tSlider:SetWidth(180)
	tSlider:SetMinMaxValues(addon:getConfig("base", "timerMin"), addon:getConfig("base", "timerMax"))
	tSlider:SetValueStep(addon:getConfig("base", "timerStep"))
	tSlider:SetValue(addon:getConfig("auction", "timer"))
	
	-- Min/max/value label
	local tsName = tSlider:GetName()
	_G[tsName .. "Low"]:SetText(addon:getConfig("base", "timerMin"))
	_G[tsName .. "High"]:SetText(addon:getConfig("base", "timerMax"))
	_G[tsName .. "Text"]:SetText(addon:getConfig("auction", "timer"))

	tSlider:SetScript("OnValueChanged", function(self)
		_G[tsName .. "Text"]:SetText(self:GetValue())
		addon:setConfig("auction", "timer", tSlider:GetValue())
	end)

	-- MinBid slider label
	local mbLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	mbLabel:SetTextColor(0.1, 1, 1, 1)
	mbLabel:SetText("Min. Bid")
	mbLabel:ClearAllPoints()
	mbLabel:SetPoint("TOPLEFT", tSlider, "BOTTOMLEFT", 0, -10)
	
	-- Timer slider
	local mbSlider = CreateFrame("Slider", "wlMinBidSlider", frame, "OptionsSliderTemplate")
	mbSlider:ClearAllPoints()
	mbSlider:SetPoint("TOPLEFT", mbLabel, "BOTTOMLEFT", 0, -5)
	mbSlider:SetWidth(180)
	mbSlider:SetMinMaxValues(addon:getConfig("base", "minBidMin"), addon:getConfig("base", "minBidMax"))
	mbSlider:SetValueStep(addon:getConfig("base", "minBidStep"))
	mbSlider:SetValue(addon:getConfig("auction", "minBid"))
	
	-- Min/max/value label
	local mbName = mbSlider:GetName()
	_G[mbName .. "Low"]:SetText(addon:getConfig("base", "minBidMin"))
	_G[mbName .. "High"]:SetText(addon:getConfig("base", "minBidMax"))
	_G[mbName .. "Text"]:SetText(addon:getConfig("auction", "minBid"))

	mbSlider:SetScript("OnValueChanged", function(self)
		_G[mbName .. "Text"]:SetText(self:GetValue())
		addon:setConfig("auction", "minBid", mbSlider:GetValue())
	end)
	
	-- Time left
	local afTimeLeftLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	afTimeLeftLabel:SetTextColor(0.1, 1, 1, 1)
	afTimeLeftLabel:SetText("Time Left")
	afTimeLeftLabel:ClearAllPoints()
	afTimeLeftLabel:SetPoint("TOPLEFT", afItemName, "BOTTOMLEFT", 200, -10)

	afTimeLeft = CreateFrame("EditBox", "wlTimeLeft", frame)
	afTimeLeft:ClearAllPoints()
	afTimeLeft:SetPoint("TOPLEFT", afTimeLeftLabel, "BOTTOMLEFT", 0, -5)
	afTimeLeft:SetFontObject(ChatFontNormal)
	afTimeLeft:SetWidth(180)
	afTimeLeft:SetHeight(20)
	afTimeLeft:SetBackdropColor(0.4, 0,4, 0,4, 0.7)
	afTimeLeft:SetText("")
	afTimeLeft:SetAutoFocus(false)
	afTimeLeft:SetMultiLine(false)
	afTimeLeft:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	local afTimeLeftTex = getTexture(afTimeLeft)
	afTimeLeftTex:SetTexture(0.3, 0.3, 0.3, 0.7)
	
	-- Current high bid
	local afCurBidLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	afCurBidLabel:SetTextColor(0.1, 1, 1, 1)
	afCurBidLabel:SetText("Cur. bid")
	afCurBidLabel:ClearAllPoints()
	afCurBidLabel:SetPoint("TOPLEFT", afTimeLeft, "BOTTOMLEFT", 0, -10)
	
	local afCurBid = CreateFrame("EditBox", "wlCurBid", frame)
	afCurBid:ClearAllPoints()
	afCurBid:SetPoint("TOPLEFT", afCurBidLabel, "BOTTOMLEFT", 0, -5)
	afCurBid:SetFontObject(ChatFontNormal)
	afCurBid:SetWidth(180)
	afCurBid:SetHeight(20)
	afCurBid:SetBackdropColor(0.4, 0,4, 0,4, 0.7)
	afCurBid:SetText("")
	afCurBid:SetAutoFocus(false)
	afCurBid:SetMultiLine(false)
	afCurBid:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	local afCurBidTex = getTexture(afCurBid)
	afCurBidTex:SetTexture(0.3, 0.3, 0.3, 0.7)
	
	-- Winner label
	local afWinnerLabel = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	afWinnerLabel:SetTextColor(0.1, 1, 1, 1)
	afWinnerLabel:SetText("Winner")
	afWinnerLabel:ClearAllPoints()
	afWinnerLabel:ClearAllPoints()
	afWinnerLabel:SetPoint("TOPLEFT", mbSlider, "BOTTOMLEFT", 0, -10)

	local afHighBidders = CreateFrame("EditBox", "wlWinner", frame)
	afHighBidders:ClearAllPoints()
	afHighBidders:SetPoint("TOPLEFT", afWinnerLabel, "BOTTOMLEFT", 0, -5)
	afHighBidders:SetFontObject(ChatFontNormal)
	afHighBidders:SetWidth(frame:GetWidth()-20)
	afHighBidders:SetHeight(20)
	afHighBidders:SetBackdropColor(0.4, 0.4, 0.4, 0.7)
	afHighBidders:SetText("")
	afHighBidders:SetAutoFocus(false)
	afHighBidders:SetMultiLine(false)
	afHighBidders:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	local afHighTex = getTexture(afHighBidders)
	afHighTex:SetTexture(0.3, 0.3, 0.3, 0.7)

	-- These functions are to be overloaded
	frame.startAuction = function () return end
	frame.stopAuction = function () return end
	frame.cancelAuction = function () return end
	frame.onUpdate = function() return end
	frame:SetScript("OnUpdate", function(self) frame.onUpdate() end)
	
-- buttons
	-- Start button
	local startButton = CreateFrame("Button", "wlStartButton", frame, "UIPanelButtonTemplate2")
	startButton:SetWidth(150)
	startButton:SetHeight(20)
	startButton:SetText("Start auction")
	startButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 10, 40)
	startButton:SetScript("OnClick", function(self)
		frame.startAuction()
	end)
	
	-- Stop button
	local stopButton = CreateFrame("Button", "wlStopButton", frame, "UIPanelButtonTemplate2")
	stopButton:SetWidth(150)
	stopButton:SetHeight(20)
	stopButton:SetText("Stop auction")
	stopButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 10, 10)
	stopButton:SetScript("OnClick", function(self)
		frame.stopAuction()
	end)
	
	-- Cancel button	
	local cancelButton = CreateFrame("Button", "wlCancelButton", frame, "UIPanelButtonTemplate2")
	cancelButton:SetWidth(150)
	cancelButton:SetHeight(20)
	cancelButton:SetText("Cancel auction")
	cancelButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -10, 10)
	cancelButton:SetScript("OnClick", function(self)
		frame:Hide()
		frame.cancelAuction()
	end)
	
	local closeButton = CreateFrame("Button", "wlCloseButton", frame, "UIPanelCloseButton")
	closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 2, -5)
	closeButton:SetScript("OnClick", function(self)
		frame:Hide()
		frame.cancelAuction()
	end)

	--	Add the bids list frame, position to right of auction window
	local bList = wfLib:GetWLBidsList()
	bList:SetParent (frame)
	bList:SetPoint("TOPLEFT", frame, "TOPRIGHT", 5, 0)
	
	frame.updateBids = function(bNames, bNumbers)
		bList.update(bNames, bNumbers)
	end
	
	frame.clearBids = function ()
		bList.clear()
	end
	
	-- set the label texts
	frame.setLabelText = function (hdrText, item, timeLeft, curBid, winners)
		header:SetText(hdrText)
		afItemLabel:SetText(item)
		afTimeLeftLabel:SetText(timeLeft)
		afCurBidLabel:SetText(curBid)
		afWinnerLabel:SetText(winners)
	end
	
	-- set the button texts
	frame.setButtonText = function (startText, stopText, cancelText)
		startButton:SetText(startText)
		stopButton:SetText(stopText)
		cancelButton:SetText(cancelText)
	end
	
	-- set the various field texts
	frame.setFields = function (list)
		afItemName:SetText(list.item or "--")
		afTimeLeft:SetText(list.timeLeft or "0")
		afCurBid:SetText(list.curBid or "0")
		afHighBidders:SetText(list.highBidders or "")
		if list.clearBids then frame.clearBids() end
	end
	frame.setTimeLeft = function (text)
		afTimeLeft:SetText(text)
	end
	frame.setCurBid = function (text)
		afCurBid:SetText(text)
	end
	frame.setHighBidders = function (text)
		afHighBidders:SetText(text)
	end
	
	-- show and hide the bids list frame along with self
	frame:SetScript("OnShow", function (self)
		bList:Show()
	end)
	frame:SetScript("OnHide", function (self)
		bList:Hide()
	end)
	
	auctionFrame = frame
	return auctionFrame
end

--========================================================================================--
-- The list of bids for the running auction
--========================================================================================--
local bidsListFrame
local bidsListTooltip
function wfLib:GetWLBidsList()
	if bidsListFrame ~= nil then return bidsListFrame end

	-- for maintenance purposes: change these values display will follow automagically
	local fName = "wlBidsFrame"
	local bName= fName  .. "Button"
	local nButtons = 10
	local bHeight = 16
	local gap = 5
	local fWidth = 200
	local fHeight = (nButtons + 2) * bHeight + 2 * gap
	local sWidth = 20
	
	-- left and right button width divided as 75% / 25% available space: frame width - (slider width + gap space)
	local bWidth = math.floor((fWidth - (sWidth + 2*gap)) * 0.75)
	local rbWidth = math.floor((fWidth - (sWidth + 2*gap)) * 0.25)
	local bNames = {}
	local nBids = 0
	local offset = 0
	
	-- indexes of current button and selected item in bids list (for button highlighting)
	local bIndex = 0
	local sIndex = 1
	
-- Da Frame (ya man)
	local frame = CreateFrame("Frame", fName, UIParent)
	frame:Hide()
	frame:SetWidth(fWidth)
	frame:SetHeight(fHeight)
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
		edgeFile="Interface\\AddOns\\whisperloot3\\textures\\otravi-semi-full-border", edgeSize = 32,
		insets = {left = 1, right = 1, top = 20, bottom = 1},
	})
	frame:SetBackdropColor(24/255, 24/255, 24/255)
	frame:ClearAllPoints()

--	Da Context Menu Frame
	local info = {}
	local ddFrame = CreateFrame("Frame", fName.."DropDownMenu")
	ddFrame.displayMode = "MENU"
	
	--[[
	List of button attributes
	======================================================
	info.text = [STRING]  --  The text of the button
	info.value = [ANYTHING]  --  The value that UIDROPDOWNMENU_MENU_VALUE is set to when the button is clicked
	info.func = [function()]  --  The function that is called when you click the button
	info.checked = [nil, true, function]  --  Check the button if true or function returns true
	info.isTitle = [nil, true]  --  If it's a title the button is disabled and the font color is set to yellow
	info.disabled = [nil, true]  --  Disable the button and show an invisible button that still traps the mouseover event so menu doesn't time out
	info.hasArrow = [nil, true]  --  Show the expand arrow for multilevel menus
	info.hasColorSwatch = [nil, true]  --  Show color swatch or not, for color selection
	info.r = [1 - 255]  --  Red color value of the color swatch
	info.g = [1 - 255]  --  Green color value of the color swatch
	info.b = [1 - 255]  --  Blue color value of the color swatch
	info.colorCode = [STRING] -- "|cAARRGGBB" embedded hex value of the button text color. Only used when button is enabled
	info.swatchFunc = [function()]  --  Function called by the color picker on color change
	info.hasOpacity = [nil, 1]  --  Show the opacity slider on the colorpicker frame
	info.opacity = [0.0 - 1.0]  --  Percentatge of the opacity, 1.0 is fully shown, 0 is transparent
	info.opacityFunc = [function()]  --  Function called by the opacity slider when you change its value
	info.cancelFunc = [function(previousValues)] -- Function called by the colorpicker when you click the cancel button 
						(it takes the previous values as its argument)
	info.notClickable = [nil, 1]  --  Disable the button and color the font white
	info.notCheckable = [nil, 1]  --  Shrink the size of the buttons and don't display a check box
	info.owner = [Frame]  --  Dropdown frame that "owns" the current dropdownlist
	info.keepShownOnClick = [nil, 1]  --  Don't hide the dropdownlist after a button is clicked
	info.tooltipTitle = [nil, STRING] -- Title of the tooltip shown on mouseover
	info.tooltipText = [nil, STRING] -- Text of the tooltip shown on mouseover
	info.justifyH = [nil, "CENTER"] -- Justify button text
	info.arg1 = [ANYTHING] -- This is the first argument used by info.func
	info.arg2 = [ANYTHING] -- This is the second argument used by info.func
	info.fontObject = [FONT] -- font object replacement for Normal and Highlight
	info.menuTable = [TABLE] -- This contains an array of info tables to be displayed as a child menu
	]]
	ddFrame.initialize = function (self, level)
		level = level or 1
		wipe(info)

	    if level == 1 then
	        -- Create the title of the menu
	        info.isTitle = 1
	        info.notCheckable = 1
	        info.text = "Bid/Auction menu"
	        UIDropDownMenu_AddButton(info, level)
	        
	        info.isTitle = nil
	        
	        info.text = "Clear winner and price"
	        info.disabled = nil
	        info.func = function() 
	        	addon:setConfig("auction", "markedWinner1", nil)
	        	addon:setConfig("auction", "markedWinner2", nil)
	        	addon:setConfig("auction", "markedPrice", nil)
	        end
	        UIDropDownMenu_AddButton(info, level)
	        
	        info.text = string.format("Mark %s as winner", addon:getConfig("auction", "curSelectedBidder"))
	        info.tooltipText = "Mark this bidder as the auction winner."
	        info.disabled = nil
	        info.func = function()
	        	addon:setConfig("auction", "markedWinner1", addon:getConfig("auction", "curSelectedBidder"))
	        end
	        UIDropDownMenu_AddButton(info, level)
	        
	        if addon:getConfig("auction", "markedWinner1") then
	        	wfLib:dbgPrint(3, "found an earlier winner: " .. addon:getConfig("auction", "markedWinner1"))
	        	info.text = string.format("  |cff00f4f0(currently set to %s)", addon:getConfig("auction", "markedWinner1"))
	        	info.notClickable = 1
	        	UIDropDownMenu_AddButton(info, level)
	        	info.notClickable = nil	        
	        end
	        
	        info.text = string.format("Use %s for calculating price", addon:getConfig("auction", "curSelectedBid"))
	        info.tooltipText = "Use this price for calculating the auction price, according to the settings."
	        info.disabled = nil
	        info.func = function()
	        	addon:setConfig("auction", "markedPrice", addon:getConfig("auction", "curSelectedBid"))
	        end
	        UIDropDownMenu_AddButton(info, level)
	        
	        if addon:getConfig("auction", "markedPrice") then
	        	wfLib:dbgPrint(3, "found an earlier price: " .. addon:getConfig("auction", "markedPrice"))
	        	info.text = string.format("  |cff00f4f0(currently set to %s)", addon:getConfig("auction", "markedPrice"))
	        	info.notClickable = 1
	        	UIDropDownMenu_AddButton(info, level)
	        	info.notClickable = nil	        
	        end

			-- Separator
			wipe(info)
			info.text = ""
			info.notClickable = 1
	        UIDropDownMenu_AddButton(info, level)
			
	        -- Close menu item
			wipe(info)
			info.notCheckable = 1
	        info.text         = CLOSE
	        info.func         = function() CloseDropDownMenus() end
	        UIDropDownMenu_AddButton(info, level)
		end
	end
	
	frame.buttonClicked = function(btn, id, button)
		-- toggle the dropdown on rbtnup
		addon:SetCurrentSelection(_G[bName .. id]:GetText(), _G[bName .. id .. "R"]:GetText())
		if button == "RightButton" then
			ToggleDropDownMenu(1, nil, ddFrame, bName .. id .. "R", 4, 0)
		end
	end
	
-- Da Frame headder
	local header = frame:CreateFontString(nil, "OVERLAY")
	header:ClearAllPoints()
	header:SetWidth(fWidth)
	header:SetHeight(bHeight)
	header:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -14)
	header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -14)
	header:SetFont("Fonts\\FRIZQT__.TTF", 12)
	header:SetJustifyH("LEFT")
	header:SetText("Bids list")
	header:SetShadowOffset(.8, -.8)
	header:SetShadowColor(0, 0, 0, 1)

-- Da Scroll bar
	local scrollbar = CreateFrame("Slider", fName .. "ScrollBar", frame,"UIPanelScrollBarTemplate")
	scrollbar:Hide()
	local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
	scrollbg:SetAllPoints(scrollbar)
	scrollbg:SetTexture(0,0,0,0.4)
	scrollbar:SetPoint("TOPLEFT", frame,"TOPRIGHT", -1 * sWidth, (-3 * bHeight) + -1 * gap)
	scrollbar:SetPoint("BOTTOMRIGHT", frame,"BOTTOMRIGHT", 0, bHeight + gap)
	scrollbar:SetMinMaxValues(0,0)
	scrollbar:SetValueStep(1)
	scrollbar:SetWidth(sWidth)
	scrollbar:EnableMouseWheel(true)

	local function updateTooltip (id, entering)
		if entering then
			if not bidsListTooltip then
				bidsListTooltip = CreateFrame("GameTooltip", fName .. "Tooltip", UIParent, "GameTooltipTemplate")
			end
			bidsListTooltip:SetOwner(frame, "ANCHOR_CURSOR")
			
			local userDKP, dateCollected, showColumns = addon:GetUserDKP(bNames[id + offset])

			-- bail out if no dkp data returned			
			if not userDKP then return end

			bidsListTooltip:AddLine("User DKP for " .. userDKP["Name"])
			
			for i=2, table.getn(showColumns), 1 do
				bidsListTooltip:AddDoubleLine(showColumns[i], userDKP[showColumns[i]])
			end
			bidsListTooltip:AddLine("DKP collected: " .. dateCollected)
			
			bidsListTooltip:Show()
		else
			bidsListTooltip:Hide()
			bidsListTooltip:ClearLines()
		end
	end
	
	-- make sure that the left and right highlights sync on mouseEnter and mouseLeave
	local setHighlight = function (id, entering)
		local lBtn = _G[bName .. id]
		local rBtn = _G[bName .. id .. "R"]
		if (entering) then
			lBtn:LockHighlight()
			rBtn:LockHighlight()
		else
			lBtn:UnlockHighlight()
			rBtn:UnlockHighlight()
		end
		-- handle showing/hiding the tooltip
		updateTooltip(id, entering)
	end

	-- scroll the frame
	frame.scroll = function(self, delta)
		offset = offset - delta
		if offset < 0 then offset = 0 end
		if offset > (nUsers - nButtons) then offset = (nUsers - nButtons) end
		scrollbar:SetValue(offset)
	end
	
-- Da Buttons
	-- create (nButtons) buttons & overlay highlights
	for i = 1, nButtons do
		-- create L/R buttons
		local lBtn = CreateFrame("Button", bName .. i, frame, "FriendsFrameIgnoreButtonTemplate")
		lBtn:SetID(i)
		local rBtn = CreateFrame("Button", bName .. i .. "R", frame, "FriendsFrameIgnoreButtonTemplate")
		rBtn:SetID(i)
		
		-- create L/R fontstrings
		local lBtnFS = lBtn:CreateFontString(bName .. i .. "FSL", "OVERLAY", "GameFontNormal")
		lBtnFS:SetJustifyH("LEFT")
		lBtnFS:SetPoint("LEFT", lBtn, "LEFT")
		local rBtnFS = rBtn:CreateFontString(bName .. i .. "FSR", "OVERLAY", "GameFontNormal")
		rBtnFS:SetJustifyH("RIGHT")
		rBtnFS:SetPoint("RIGHT", rBtn, "RIGHT")

		-- button positioning
		if i == 1 then
			lBtn:SetPoint("TOPLEFT", header, "BOTTOMLEFT", -2, -1 * gap)
		else
			lBtn:SetPoint("TOPLEFT", _G[bName .. i - 1], "BOTTOMLEFT")
		end
		rBtn:SetPoint("TOPLEFT", lBtn, "TOPRIGHT")

		-- button height / width / textures
		lBtn:SetWidth(bWidth)
		lBtn:SetHeight(bHeight)
		lBtn:SetFontString(lBtnFS)
		lBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		rBtn:SetWidth(rbWidth)
		rBtn:SetHeight(bHeight)
		rBtn:SetFontString(rBtnFS)
		rBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		-- OnEnter / OnLeave scripts
		lBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		lBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)
				
		rBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		rBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)

		lBtn:RegisterForClicks("AnyUp")
		rBtn:RegisterForClicks("AnyUp")
		
		lBtn:SetScript ("OnClick", function(self, button, down)
				frame.buttonClicked(self:GetName(), i, button)
			end)
		rBtn:SetScript ("OnClick", function(self, button)
				frame.buttonClicked(self:GetName(), i, button)
			end)

		lBtn:EnableMouseWheel(true)
		lBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)

		rBtn:EnableMouseWheel(true)
		rBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)
	end

	-- Stick some values in the buttons in the frame (updated for scroll bar offset)
	local updating
	frame.update = function(...)
		if updating then return end
		updating = true
		
		if ... then
			bNames, bNumbers = ...
			nBids = table.getn(bNames)

			wfLib:dbgPrint(9, string.format ("-- frame received %d bids: %s", nBids, table.concat(bNames, ", ")))
			scrollbar:SetValue(0)
			if (nBids <= nButtons) then
				scrollbar:SetMinMaxValues(0,0)
				scrollbar:Hide()
			else
				scrollbar:SetMinMaxValues(0, nBids - nButtons)
				scrollbar:Show()
			end
		end
		
		-- update button texts to relevant view of bNames/bNumbers
		local lFS, rFS, lBtn, rBtn
		for i=1, nButtons, 1 do
			lBtn = _G[bName .. i]
			rBtn = _G[bName .. i .. "R"]
			lFS = _G[bName .. i .. "FSL"]
			rFS = _G[bName .. i .. "FSR"]
			if ((offset + i) <= nBids) then
				lFS:SetText(bNames[i + offset])
				rFS:SetText(bNumbers[i + offset])
				lBtn:Show()
				rBtn:Show()
			else
			    lBtn:Hide()
			    rBtn:Hide()
			end
		end
		updating = false
	end

	scrollbar:SetScript("OnValueChanged", function(self)
			offset = scrollbar:GetValue()
			frame.update(nil)
		end)
	
	scrollbar:SetScript("OnMouseWheel", function(self, delta)
		frame.scroll(self, delta)
	end)

	frame.clear = function()
		offset = 0
		frame.update({})
	end

	bidsListFrame = frame
	return bidsListFrame
end

--========================================================================================--
-- The loot list (for quick-starting auctions)
--========================================================================================--
local lootListFrame
function wfLib:GetWLLootList()
	if lootListFrame ~= nil then return lootListFrame end

	-- for maintenance purposes: change these values display will follow automagically
	local fName = "wllootFrame"
	local bName= fName  .. "Button"
	local nButtons = 10
	local bHeight = 16
	local gap = 5
	local fWidth = 200
	local fHeight = (nButtons + 2) * bHeight + 2 * gap
	local sWidth = 20
	
	-- left and right button width divided as 75% / 25% available space: frame width - (slider width + gap space)
	local bWidth = math.floor((fWidth - (sWidth + 2*gap)) * 0.75)
	local rbWidth = math.floor((fWidth - (sWidth + 2*gap)) * 0.25)
	local bNames = {}
	local nLoot = 0
	local offset = 0
	
	-- indexes of current button and selected item in loot list (for button highlighting)
	local bIndex = 0
	local sIndex = 1
	
-- Da Frame (ya man)
	local frame = CreateFrame("Frame", fName, UIParent)
	frame:Hide()
	frame:SetWidth(fWidth)
	frame:SetHeight(fHeight)
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
		edgeFile="Interface\\AddOns\\whisperloot3\\textures\\otravi-semi-full-border", edgeSize = 32,
		insets = {left = 1, right = 1, top = 20, bottom = 1},
	})
	frame:SetBackdropColor(24/255, 24/255, 24/255)
	frame:ClearAllPoints()
-- Da Frame headder
	local header = frame:CreateFontString(nil, "OVERLAY")
	header:ClearAllPoints()
	header:SetWidth(fWidth)
	header:SetHeight(bHeight)
	header:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -14)
	header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -14)
	header:SetFont("Fonts\\FRIZQT__.TTF", 12)
	header:SetJustifyH("LEFT")
	header:SetText("Bids list")
	header:SetShadowOffset(.8, -.8)
	header:SetShadowColor(0, 0, 0, 1)

-- Da Scroll bar
	local scrollbar = CreateFrame("Slider", fName .. "ScrollBar", frame,"UIPanelScrollBarTemplate")
	scrollbar:Hide()
	local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
	scrollbg:SetAllPoints(scrollbar)
	scrollbg:SetTexture(0,0,0,0.4)
	scrollbar:SetPoint("TOPLEFT", frame,"TOPRIGHT", -1 * sWidth, (-3 * bHeight) + -1 * gap)
	scrollbar:SetPoint("BOTTOMRIGHT", frame,"BOTTOMRIGHT", 0, bHeight + gap)
	scrollbar:SetMinMaxValues(0,0)
	scrollbar:SetValueStep(1)
	scrollbar:SetWidth(sWidth)
	scrollbar:EnableMouseWheel(true)

	-- make sure that the left and right highlights sync on mouseEnter and mouseLeave
	local setHighlight = function (id, entering)
		local lBtn = _G[bName .. id]
		local rBtn = _G[bName .. id .. "R"]
		if (entering) then
			lBtn:LockHighlight()
			rBtn:LockHighlight()
		else
			lBtn:UnlockHighlight()
			rBtn:UnlockHighlight()
		end
		-- handle showing/hiding the tooltip
		updateTooltip(id, entering)
	end

	-- scroll the frame
	frame.scroll = function(self, delta)
		offset = offset - delta
		if offset < 0 then offset = 0 end
		if offset > (nUsers - nButtons) then offset = (nUsers - nButtons) end
		scrollbar:SetValue(offset)
	end
	
-- Da Buttons
	-- create (nButtons) buttons & overlay highlights
	for i = 1, nButtons do
		-- create L/R buttons
		local lBtn = CreateFrame("Button", bName .. i, frame, "FriendsFrameIgnoreButtonTemplate")
		lBtn:SetID(i)
		local rBtn = CreateFrame("Button", bName .. i .. "R", frame, "FriendsFrameIgnoreButtonTemplate")
		rBtn:SetID(i)
		
		-- create L/R fontstrings
		local lBtnFS = lBtn:CreateFontString(bName .. i .. "FSL", "OVERLAY", "GameFontNormal")
		lBtnFS:SetJustifyH("LEFT")
		lBtnFS:SetPoint("LEFT", lBtn, "LEFT")
		local rBtnFS = rBtn:CreateFontString(bName .. i .. "FSR", "OVERLAY", "GameFontNormal")
		rBtnFS:SetJustifyH("RIGHT")
		rBtnFS:SetPoint("RIGHT", rBtn, "RIGHT")

		-- button positioning
		if i == 1 then
			lBtn:SetPoint("TOPLEFT", header, "BOTTOMLEFT", -2, -1 * gap)
		else
			lBtn:SetPoint("TOPLEFT", _G[bName .. i - 1], "BOTTOMLEFT")
		end
		rBtn:SetPoint("TOPLEFT", lBtn, "TOPRIGHT")

		-- button height / width / textures
		lBtn:SetWidth(bWidth)
		lBtn:SetHeight(bHeight)
		lBtn:SetFontString(lBtnFS)
		lBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		rBtn:SetWidth(rbWidth)
		rBtn:SetHeight(bHeight)
		rBtn:SetFontString(rBtnFS)
		rBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		-- OnEnter / OnLeave scripts
		lBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		lBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)
				
		rBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		rBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)

		lBtn:RegisterForClicks("AnyUp")
		rBtn:RegisterForClicks("AnyUp")
		
		lBtn:SetScript ("OnClick", function(self, button, down)
				frame.buttonClicked(self:GetName(), i, button)
			end)
		rBtn:SetScript ("OnClick", function(self, button)
				frame.buttonClicked(self:GetName(), i, button)
			end)

		lBtn:EnableMouseWheel(true)
		lBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)

		rBtn:EnableMouseWheel(true)
		rBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)
	end

	-- Stick some values in the buttons in the frame (updated for scroll bar offset)
	local updating
	frame.update = function(...)
		if updating then return end
		updating = true
		
		if ... then
			bNames, bNumbers = ...
			nBids = table.getn(bNames)

			wfLib:dbgPrint(9, string.format ("-- frame received %d loot: %s", nBids, table.concat(bNames, ", ")))
			scrollbar:SetValue(0)
			if (nBids <= nButtons) then
				scrollbar:SetMinMaxValues(0,0)
				scrollbar:Hide()
			else
				scrollbar:SetMinMaxValues(0, nBids - nButtons)
				scrollbar:Show()
			end
		end
		
		-- update button texts to relevant view of bNames/bNumbers
		local lFS, rFS, lBtn, rBtn
		for i=1, nButtons, 1 do
			lBtn = _G[bName .. i]
			rBtn = _G[bName .. i .. "R"]
			lFS = _G[bName .. i .. "FSL"]
			rFS = _G[bName .. i .. "FSR"]
			if ((offset + i) <= nBids) then
				lFS:SetText(bNames[i + offset])
				rFS:SetText(bNumbers[i + offset])
				lBtn:Show()
				rBtn:Show()
			else
			    lBtn:Hide()
			    rBtn:Hide()
			end
		end
		updating = false
	end

	scrollbar:SetScript("OnValueChanged", function(self)
			offset = scrollbar:GetValue()
			frame.update(nil)
		end)
	
	scrollbar:SetScript("OnMouseWheel", function(self, delta)
		frame.scroll(self, delta)
	end)

	frame.clear = function()
		offset = 0
		frame.update({})
	end

	lootListFrame = frame
	return lootListFrame
end

--========================================================================================--
-- The DKP entry frame (/wl3 setdkp)
--========================================================================================--
local dkpEntryFrame
function wfLib:GetWLDKPEntryFrame(...)
	local newCopy, globalName, title = ...
	if dkpFrame ~= nil and not newCopy then return dkpFrame end
	
	fName = globalName or "wlDKPEntry"
	
	local frame = CreateFrame("Frame", fName, UIParent)
	frame:Hide()
	frame:SetWidth(600)
	frame:SetHeight(400)
	frame:SetResizable(true)

	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
		edgeFile="Interface\\AddOns\\whisperloot3\\textures\\otravi-semi-full-border", edgeSize = 32,
		insets = {left = 1, right = 1, top = 20, bottom = 1},
	})
	
	frame:SetBackdropColor(24/255, 24/255, 24/255)
	frame:ClearAllPoints()
	
	frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
	frame:EnableMouse(true)
	frame:RegisterForDrag("LeftButton")
	frame:SetMovable(true)

	frame:SetScript("OnDragStart", function(self)
		self:StartMoving()
	end)
	frame:SetScript("OnDragStop", function(self)
		self:StopMovingOrSizing()
	end)

-- Frame header
	local header = frame:CreateFontString(nil,"OVERLAY")
	header:ClearAllPoints()
	header:SetWidth(240)
	header:SetHeight(15)
	header:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -14)
	header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -14)
	header:SetFont("Fonts\\FRIZQT__.TTF", 12)
	header:SetJustifyH("LEFT")
	header:SetText(title or "Enter DKP Standings")
	header:SetShadowOffset(.8, -.8)
	header:SetShadowColor(0, 0, 0, 1)

	local scroll = CreateFrame("ScrollFrame", fName .. "Scroll", frame, "UIPanelScrollFrameTemplate")
	scroll:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -40)
	scroll:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 40)
	
	local dkpBox = CreateFrame("EditBox", fName .. "EditBox", scroll)
	dkpBox:SetPoint("TOPLEFT", scroll, "TOPLEFT", 2, -2)
	dkpBox:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 2)
	dkpBox:SetBackdropColor(0.4, 0.4, 0.4, 0.3)
	dkpBox:SetWidth(1024)
	dkpBox:SetHeight(800)
	dkpBox:SetMultiLine(true)
	dkpBox:SetAutoFocus(true)
	dkpBox:EnableMouse(true)
	dkpBox:SetFontObject(GameFontNormal)
	dkpBox:SetScript("OnTextChanged", function(self) 
			scroll:UpdateScrollChildRect()
		end)
	
	scroll:SetScrollChild(dkpBox)
		
--	To Be Overloaded
	frame.processDKP = function(value) end
	
	-- Stop button
	local startButton = CreateFrame("Button", fName .. "StartButton", frame, "UIPanelButtonTemplate2")
	startButton:SetWidth(150)
	startButton:SetHeight(20)
	startButton:SetText("Process DKP")
	startButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 10, 10)
	startButton:SetScript("OnClick", function(self)
		frame:Hide()
		frame.processDKP(dkpBox:GetText())
	end)
	
	-- Cancel button	
	local cancelButton = CreateFrame("Button", fName .. "CancelButton", frame, "UIPanelButtonTemplate2")
	cancelButton:SetWidth(150)
	cancelButton:SetHeight(20)
	cancelButton:SetText("Cancel")
	cancelButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -10, 10)
	cancelButton:SetScript("OnClick", function(self)
		dkpBox:SetText("")
		frame:Hide()
	end)

	frame.setSize = function(width, height)
		frame:ClearAllPoints()
		frame:SetWidth(width)
		frame:SetHeight(height)
		
		scroll:SetPoint("TOPLEFT", frame, "TOPLEFT", 5, -40)
		scroll:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 40)

		startButton:SetWidth(math.floor(width/2)-10)
		startButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 5, 10)
		cancelButton:SetWidth(math.floor(width/2)-10)
		cancelButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -5, 10)
	end

	frame.setTitle = function(title)
		header:SetText("title")
	end
		
	frame.hideStartBtn = function()
		startButton:Hide()
	end

	frame.setText = function(text)
		dkpBox:SetText(text)
	end
	frame.addText = function(text)
		dkpBox:Insert(text)
	end
	
	frame.setEditable = function(isEditable)
		if isEditable then
			dkpBox:SetScript("OnEditFocusGained", nil)
		else
			dkpBox:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
		end
	end
	
	dkpEntryFrame = frame
	return dkpEntryFrame	
end

--========================================================================================--
-- The DKP list frame - Faux scrollframe version with tooltip (/wl3 showdkp)
--========================================================================================--
local userDKPFrame
local userDKPTooltip
function wfLib:GetWLDKPListFrame()
	if userDKPFrame ~= nil then return userDKPFrame end

	wfLib:dbgPrint(1, "Setting up new User DKP frame")
	
	-- for maintenance purposes: change these values display will follow automagically
	local fName = "wlDKPListFrame"
	local bName= fName  .. "Button"
	local nButtons = 20
	local bHeight = 16
	local gap = 5
	local fWidth = 300
	local fHeight = (nButtons + 4) * bHeight + 6 * gap
	local sWidth = 20
	-- left and right button width divided as 75% / 25% available space: frame width - (slider width + gap space)
	local bWidth = math.floor((fWidth - (sWidth + 2 * gap)) * 0.75)
	local rbWidth = math.floor((fWidth - (sWidth + 2 * gap)) * 0.25)
	
	local userDKP = {}
	local userNames = {}
	local showColumns = {}
	local nUsers = 0
	local offset = 0

-- Da Frame (ya man)
	local frame = CreateFrame("Frame", fName, UIParent)
	frame:Hide()
	frame:SetWidth(fWidth)
	frame:SetHeight(fHeight)
	
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
		edgeFile="Interface\\AddOns\\whisperloot3\\textures\\otravi-semi-full-border", edgeSize = 32,
		insets = {left = 1, right = 1, top = 20, bottom = 1},
	})
	frame:ClearAllPoints()
	frame:SetBackdropColor(24/255, 24/255, 24/255)
	
	frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
	frame:EnableMouse(true)
	frame:RegisterForDrag("LeftButton")
	frame:SetMovable(true)

	frame:SetScript("OnDragStart", function(self)
		self:StartMoving()
	end)
	frame:SetScript("OnDragStop", function(self)
		self:StopMovingOrSizing()
	end)

-- Da Frame header
	local header = frame:CreateFontString(nil, "OVERLAY")
	header:ClearAllPoints()
	header:SetWidth(fWidth)
	header:SetHeight(bHeight)
	header:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -14)
	header:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -14)
	header:SetFont("Fonts\\FRIZQT__.TTF", 12)
	header:SetJustifyH("LEFT")
	header:SetText("User DKP")
	header:SetShadowOffset(.8, -.8)
	header:SetShadowColor(0, 0, 0, 1)

	local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	label:SetTextColor(0.1, 1, 1, 1)
	label:SetText("")
	label:ClearAllPoints()
	label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -2 * bHeight - gap)
	label:SetWidth(fWidth)
	label:SetHeight(bHeight)

	-- "show raid only" checkbox
	local raidCBtn = CreateFrame("Checkbutton", fName .. "ROCBox", frame, "OptionsCheckButtonTemplate")
	raidCBtn:ClearAllPoints()
	raidCBtn:SetWidth(20)
	raidCBtn:SetHeight(20)
	_G[raidCBtn:GetName().."Text"]:SetText("Show Raid only")
	raidCBtn:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", gap, gap)

	-- Da Scroll bar
	local scrollbar = CreateFrame("Slider", fName .. "ScrollBar", frame,"UIPanelScrollBarTemplate")
	scrollbar:Hide()
	local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
	scrollbg:SetAllPoints(scrollbar)
	scrollbg:SetTexture(0,0,0,0.4)
	scrollbar:SetPoint("TOPLEFT", label,"BOTTOMRIGHT", -sWidth, -gap)
	scrollbar:SetPoint("BOTTOMRIGHT", frame,"BOTTOMRIGHT", 0, 2 * bHeight + 3 * gap)
	scrollbar:SetMinMaxValues(0,0)
	scrollbar:SetValueStep(3)
	scrollbar:SetWidth(sWidth)
	scrollbar:EnableMouseWheel(true)

	local function updateTooltip (id, entering)
		if entering then
			if not newUserDKPTooltip then
				newUserDKPTooltip = CreateFrame("GameTooltip", fName .. "Tooltip", UIParent, "GameTooltipTemplate")
			end
			newUserDKPTooltip:SetOwner(frame, "ANCHOR_CURSOR")
			
			local entryDKP = userDKP[userNames[id + offset]]

			-- bail out if no dkp data returned			
			if not entryDKP then return end

			newUserDKPTooltip:AddLine("User DKP for " .. entryDKP["Name"])
			
			for i=2, table.getn(showColumns), 1 do
				newUserDKPTooltip:AddDoubleLine(showColumns[i], entryDKP[showColumns[i]])
			end
			newUserDKPTooltip:AddLine("DKP collected: " .. userDKP["DATE_COLLECTED"])
			
			newUserDKPTooltip:Show()
		else
			newUserDKPTooltip:Hide()
			newUserDKPTooltip:ClearLines()
		end
	end
	
	-- make sure that the left and right highlights sync on mouseEnter and mouseLeave
	local setHighlight = function (id, entering)
		local lBtn = _G[bName .. id]
		local rBtn = _G[bName .. id .. "R"]
		if (entering) then
			lBtn:LockHighlight()
			rBtn:LockHighlight()
		else
			lBtn:UnlockHighlight()
			rBtn:UnlockHighlight()
		end
		-- handle showing/hiding the tooltip
		updateTooltip(id, entering)
	end
	
	-- scroll the frame
	frame.scroll = function(self, delta)
		offset = offset - delta * 3												-- scroll per 3 lines
		if offset < 0 then offset = 0 end										-- set to show first page
		if offset > (nUsers - nButtons) then offset = (nUsers - nButtons) end	-- set to show last page of users
		scrollbar:SetValue(offset)
	end
	
	-- create (nButtons) buttons & overlay highlights
	for i = 1, nButtons do
		-- create L/R buttons
		local lBtn = CreateFrame("Button", bName .. i, frame, "FriendsFrameIgnoreButtonTemplate")
		lBtn:SetID(i)
		local rBtn = CreateFrame("Button", bName .. i .. "R", frame, "FriendsFrameIgnoreButtonTemplate")
		rBtn:SetID(i)
		
		-- create L/R fontstrings
		local lBtnFS = lBtn:CreateFontString(bName .. i .. "FSL", "OVERLAY", "GameFontNormal")
		lBtnFS:SetJustifyH("LEFT")
		lBtnFS:SetPoint("LEFT", lBtn, "LEFT")
		local rBtnFS = rBtn:CreateFontString(bName .. i .. "FSR", "OVERLAY", "GameFontNormal")
		rBtnFS:SetJustifyH("RIGHT")
		rBtnFS:SetPoint("RIGHT", rBtn, "RIGHT")

		-- button positioning
		if i == 1 then
			lBtn:SetPoint("TOPLEFT", label, "BOTTOMLEFT", gap, -gap)
		else
			lBtn:SetPoint("TOPLEFT", _G[bName .. i - 1], "BOTTOMLEFT")
		end
		rBtn:SetPoint("TOPLEFT", lBtn, "TOPRIGHT")

		-- button height / width / textures
		lBtn:SetWidth(bWidth)
		lBtn:SetHeight(bHeight)
		lBtn:SetFontString(lBtnFS)
		lBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		rBtn:SetWidth(rbWidth)
		rBtn:SetHeight(bHeight)
		rBtn:SetFontString(rBtnFS)
		rBtn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

		-- OnEnter / OnLeave scripts
		lBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		lBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)
				
		rBtn:SetScript ("OnEnter", function(self)
			setHighlight(self:GetID(), true)
		end)
		rBtn:SetScript ("OnLeave", function(self)
			setHighlight(self:GetID(), false)
		end)
		
		lBtn:EnableMouseWheel(true)
		lBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)

		rBtn:EnableMouseWheel(true)
		rBtn:SetScript("OnMouseWheel", function(self, delta)
			frame.scroll(self, delta)
		end)
	end

	-- Stick some values in the buttons in the frame (updated for scroll bar offset)
	local updating
	frame.update = function()
		if updating then return end
		updating = true

		local raidOnly = addon:getConfig("base", "raidDKPOnly")

		-- update button texts to relevant view of bNames/bNumbers
		local lFS, rFS, lBtn, rBtn
		
		for i=1, nButtons, 1 do
			lBtn = _G[bName .. i]
			rBtn = _G[bName .. i .. "R"]
			lFS = _G[bName .. i .. "FSL"]
			rFS = _G[bName .. i .. "FSR"]
			if ((offset + i) <= nUsers) then
				wfLib:dbgPrint(3, string.format("Adding %s to window", userNames[i + offset]))
				lFS:SetText(userNames[i + offset])
				if userDKP[userNames[i + offset]] ~= nil then
					rFS:SetText(userDKP[userNames[i + offset]].Current)
				else
					rFS:SetText("No Data")
				end
				lBtn:Show()
				rBtn:Show()
			else
			    lBtn:Hide()
			    rBtn:Hide()
			end
		end

		updating = false
	end

	frame.getUserDKPList = function()
		userNames = {}
		userDKP, showColumns = addon:GetUserDKP(nil)

		if addon:getConfig("base", "raidDKPOnly") and UnitInRaid("player") then
			userNames = addon:getConfig("base", "raidMemberList")
			
			-- debugging code
			if debug then
				for i=1, table.getn(userNames), 1 do
					wfLib:dbgPrint(9, userNames[i])
				end
			end
		else
			for k,v in pairs(userDKP) do
				if (k ~= "DATE_COLLECTED") then
					table.insert(userNames, k)
				end
			end
		end		

		table.sort(userNames)
		nUsers = table.getn(userNames)
		
		offset = 0
		if (nUsers <= nButtons) then
			scrollbar:SetMinMaxValues(0,0)
			scrollbar:Hide()
		else
			scrollbar:SetMinMaxValues(0, nUsers - nButtons)
			scrollbar:SetValue(0)
			scrollbar:Show()
		end

		label:SetText("DKP collected " .. userDKP["DATE_COLLECTED"])

		raidCBtn:SetChecked(addon:getConfig("base", "raidDKPOnly"))
	end
	
	frame:SetScript("OnShow", function(self)
		wfLib:dbgPrint(9, fName .. "self:OnShow(self)")
		frame.getUserDKPList()
		frame.update()
	end)

	scrollbar:SetScript("OnValueChanged", function(self)
		offset = scrollbar:GetValue()
		frame.update()
	end)

	scrollbar:SetScript("OnMouseWheel", function(self, delta)
		frame.scroll(self, delta)
	end)

	raidCBtn:SetScript("OnClick", function(self) 
		addon:setConfig("base", "raidDKPOnly", self:GetChecked())
		frame.getUserDKPList()
		frame.update()
	end)
	
	-- Cancel button	
	local cancelButton = CreateFrame("Button", fName .. "CancelButton", frame, "UIPanelButtonTemplate2")
	cancelButton:SetWidth(50)
	cancelButton:SetHeight(20)
	cancelButton:SetText("Cancel")
	cancelButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -gap, gap)
	cancelButton:SetScript("OnClick", function(self)
		frame:Hide()
	end)
	
	userDKPFrame = frame
	return userDKPFrame
end

--========================================================================================--
-- The Loot list frame (using Tablet)
--========================================================================================--
--local instanceCols = {"Instance", "Date"}
--local instanceJustify = {"LEFT", "LEFT"}
--local lootCols = {"Winner", "DKP", "Item"}
--local lootJustify = {"LEFT", "RIGHT", "LEFT"}
--local selInstName = nil
--local selInstDate = nil
--
--function wfLib:ShowWLLootList(instanceLoot)
--	local instName, instDate, instLoot, curSelection
--
--	if selInstName == nil then
--		selInstName = GetRealZoneText()
--		selInstDate = today
--	end
--	
--	-- Check instance selection (instance, date)
--	-- Populate loot frame
--	--		Recorded instances list
--	--		loot for selected instance
--	-- Show frame
--	
--	-- Add instance list
--	local cat = tablet:AddCategory("columns", #instanceCols)
--	local line = {}
--	for i = 1, #instanceCols do
--		if i == 1 then
--			line['text'] = instanceCols[i]
--			line['justify'] = instanceJustify[i]
--		else
--			line['text'..i] = instanceCols[i]
--			line['justify'..i] = instanceJustify[i]
--		end
--	end
--	line["istitle"] = true
--	cat:AddLine(header)
--
--	curSelection = false
--	for k, v in ipairs(InstanceLoot) do
--		line = {}
--		instName, instDate = strsplit("|", k)
--		if instName == selInstName and instDate == selInstDate then
--			instLoot = v
--			curSelection = true
--		else
--			curSelection = false
--		end
--		line["hascheck"] = true
--		line["checked"] = curSelection
--		line["text"] = instName
--		line["justify"] = lootJustify[1]
--
--		line["text2"] = instDate
--		line["justify2"] = instanceJustify[2]
--
--		line['func'] = function(self, instName, instDate)
--				selInstName = instName
--				selInstDate = instDate
--			end
--		cat:AddLine(line)
--	end
--	
--	-- Add instance loot
--	tablet:AddCategory("columns", #lootCols)
--	line = {}
--	for i = 1, #lootCols do
--		if i == 1 then
--			line['text'] = v[i]
--			header['justify'] = lootJustify[i]
--		else
--			header['text'..i] = v[i]
--			header['justify'..i] = lootJustify[i]
--		end
--	end
--	line["istitle"] = true
--	cat:AddLine(header)
--
--	local lootLine
--	for _, v in  ipairs(instLoot) do
--		line = {}
--		for i = 1, #v do
--			if j == 1 then
--				line['text'] = v[i]
--				line['justify'] = lootJustify[i]
--			else
--				line['text'..i] = v[i]
--				line['justify'..i] = lootJustify[i]
--			end
--		end
--		
--		cat:AddLine(line)
--	end	
--	
--	return 
--end

--========================================================================================--
-- Embeds wfLib into the target object making the functions from the mixins list available on target:..
-- target (object) - target object to embed AceBucket in
--========================================================================================--

local mixins = {
	"GetWLAuctionFrame", "GetWLDKPEntryFrame", "GetWLDKPListFrame", "GetWLDKPListFrame_NEW", "SetDebug",
} 

function wfLib:Embed( target )
	for k, v in pairs( mixins ) do
		target[v] = self[v]
	end
	self.embeds[target] = true
	return target
end

function wfLib:OnEmbedEnable( target )
	if wfLib.weakcommands[target] then
		for command, func in pairs( wfLib.weakcommands[target] ) do
			target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
		end
	end
end

function wfLib:OnEmbedDisable( target )
	if wfLib.weakcommands[target] then
		for command, func in pairs( wfLib.weakcommands[target] ) do
			target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
		end
	end
end

for addon in pairs(wfLib.embeds) do
	wfLib:Embed(addon)
end
